home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / CBGRX103.ZIP / contrib / libgrx / fntool / readbdf.c < prev    next >
Text File  |  1993-12-06  |  7KB  |  296 lines

  1. #include "fntool.h"
  2.  
  3. typedef struct {
  4.     int bbw,bbh;
  5.     int bbx,bby;
  6. } bbox;
  7.  
  8. static char **bmp;
  9. static bbox fontbb;
  10. static bbox charbb;
  11. static int  ascent;
  12. static int  descent;
  13. static int  defchar;
  14.  
  15. static void badbdf(char *msg)
  16. {
  17.     fatalerr("invalid \".bdf\" file: \"%s\" -- %s",inname,msg);
  18. }
  19.  
  20. static void readbitmap(void)
  21. {
  22.     char *bp;
  23.     int ww = charbb.bbw;
  24.     int hh = charbb.bbh;
  25.     int y0 = fontbb.bbh - hh - (charbb.bby - fontbb.bby);
  26.     int x,y,bits;
  27.  
  28.     if((charbb.bbw > fontbb.bbw) || (charbb.bbh > fontbb.bbh))
  29.         badbdf("bounding box error");
  30.     if((charbb.bbx < fontbb.bbx) || (charbb.bby < fontbb.bby))
  31.         badbdf("bounding box error");
  32.     if(bmp == NULL)
  33.         bmp = makebytemap(fontbb.bbw,fontbb.bbh);
  34.     setbytemap(bmp,0,0,0,fontbb.bbw,fontbb.bbh);
  35.     for(y = 0; y < hh; y++) {
  36.         bp = readline();
  37.         for(bits = x = 0; x < ww; x++) {
  38.         if((x & 3) == 0) {
  39.             bits = *bp++;
  40.             if(!isxdigit(bits)) {
  41.             if(x == 0) badbdf("invalid bitmap digit");
  42.             bits = 0;
  43.             }
  44.             else if(isdigit(bits)) bits -= '0';
  45.             else if(isupper(bits)) bits -= ('A' - 10);
  46.             else bits -= ('a' - 10);
  47.         }
  48.         bmp[y0+y][x] = (bits & 8) ? 1 : 0;
  49.         bits <<= 1;
  50.         }
  51.     }
  52. }
  53.  
  54. static chr *buildchar(chr *temp)
  55. {
  56.     int wdt = temp->width;
  57.     int pos = 0;
  58.     int cpy = charbb.bbw;
  59.     chr *result;
  60.  
  61.     if(charbb.bbx > 0)
  62.         pos = charbb.bbx;
  63.     else if(charbb.bbx < 0)
  64.         wdt -= charbb.bbx;
  65.     if((pos + cpy) > wdt) wdt = pos + cpy;
  66.     temp->width = wdt;
  67.     temp->bmp = makebytemap(wdt,fnt.height);
  68.     copybytemap(temp->bmp,pos,0,bmp,0,0,cpy,fontbb.bbh);
  69.     result = safemalloc(sizeof(chr));
  70.     *result = *temp;
  71.     return(result);
  72. }
  73.  
  74. static void readchar(void)
  75. {
  76.     char *buff;
  77.     chr  *cp,newch;
  78.     chr  *prv,*nxt;
  79.  
  80.     memset(&newch,0,sizeof(chr));
  81.     newch.code = (-1);
  82.     charbb = fontbb;
  83.     for( ; ; ) {
  84.         buff = readline();
  85.         if(strmatch(buff,"ENCODING")) {
  86.         sscanf(buff,"ENCODING %d",&newch.code);
  87.         continue;
  88.         }
  89.         if(strmatch(buff,"DWIDTH")) {
  90.         sscanf(buff,"DWIDTH %d",&newch.width);
  91.         continue;
  92.         }
  93.         if(strmatch(buff,"BBX")) {
  94.         sscanf(buff,
  95.             "BBX %d %d %d %d",
  96.             &charbb.bbw,&charbb.bbh,&charbb.bbx,&charbb.bby
  97.         );
  98.         continue;
  99.         }
  100.         if(strmatch(buff,"BITMAP")) {
  101.         readbitmap();
  102.         break;
  103.         }
  104.     }
  105.     if(newch.code < 0) return;
  106.     cp = buildchar(&newch);
  107.     for(prv = NULL,nxt = fnt.chars; nxt != NULL; prv = nxt,nxt = nxt->next) {
  108.         if(nxt->code == cp->code) badbdf("repeated character");
  109.         if(nxt->code > cp->code) break;
  110.     }
  111.     cp->next = nxt;
  112.     *(prv ? &prv->next : &fnt.chars) = cp;
  113. }
  114.  
  115. static void scanstr(char *line,char *buf)
  116. {
  117.     if((line = strchr(line,'"')) != NULL) for( ; ; ) {
  118.         if(*++line != '"') {
  119.         *buf++ = *line;
  120.         if(*line == '\0') break;
  121.         continue;
  122.         }
  123.         if(line[1] == '"') {
  124.         *buf++ = '"';
  125.         line++;
  126.         continue;
  127.         }
  128.         break;
  129.     }
  130.     *buf = '\0';
  131. }
  132.  
  133. static void readfont(void)
  134. {
  135.     char *buff;
  136.     char token[100];
  137.     int  ii;
  138.  
  139.     bmp = NULL;
  140.     for( ; ; ) {
  141.         buff = readline();
  142.         if(strmatch(buff,"FONTBOUNDINGBOX")) {
  143.         sscanf(buff,
  144.             "FONTBOUNDINGBOX %d %d %d %d",
  145.             &fontbb.bbw,&fontbb.bbh,&fontbb.bbx,&fontbb.bby
  146.         );
  147.         if(fontbb.bbh > fnt.height) fnt.height = fontbb.bbh;
  148.         continue;
  149.         }
  150.         if(strmatch(buff,"FAMILY_NAME")) {
  151.         scanstr(buff,fnt.family);
  152.         continue;
  153.         }
  154.         if(strmatch(buff,"WEIGHT_NAME")) {
  155.         scanstr(buff,token);
  156.         if(strmatch(token,"bold"))
  157.             strcpy(fnt.weight,"bold");
  158.         else if(strmatch(token,"thin"))
  159.             strcpy(fnt.weight,"thin");
  160.         continue;
  161.         }
  162.         if(strmatch(buff,"SLANT")) {
  163.         scanstr(buff,token);
  164.         switch(tolower(token[0])) {
  165.           case 'i':
  166.           case 'o':
  167.             strcpy(fnt.slant,"ital");
  168.             break;
  169.         }
  170.         continue;
  171.         }
  172.         if(strmatch(buff,"SPACING")) {
  173.         scanstr(buff,token);
  174.         switch(tolower(token[0])) {
  175.           case 'p':
  176.             fnt.isfixed = 0;
  177.             break;
  178.           case 'c':
  179.           case 'm':
  180.             fnt.isfixed = 1;
  181.             break;
  182.         }
  183.         continue;
  184.         }
  185.         if(strmatch(buff,"PIXEL_SIZE")) {
  186.         sscanf(buff,"PIXEL_SIZE %d",&ii);
  187.         if(ii > fnt.height) fnt.height = ii;
  188.         continue;
  189.         }
  190.         if(strmatch(buff,"FONT_DESCENT")) {
  191.         sscanf(buff,"FONT_DESCENT %d",&descent);
  192.         continue;
  193.         }
  194.         if(strmatch(buff,"FONT_ASCENT")) {
  195.         sscanf(buff,"FONT_ASCENT %d",&ascent);
  196.         continue;
  197.         }
  198.         if(strmatch(buff,"DEFAULT_CHAR")) {
  199.         sscanf(buff,"DEFAULT_CHAR %d",&defchar);
  200.         continue;
  201.         }
  202.         if(strmatch(buff,"FONT ")) {
  203.         strcat(notes,buff);
  204.         continue;
  205.         }
  206.         if(strmatch(buff,"COPYRIGHT")) {
  207.         strcat(notes,buff);
  208.         continue;
  209.         }
  210.         if(strmatch(buff,"COMMENT")) {
  211.         strcat(notes,&buff[8]);
  212.         continue;
  213.         }
  214.         if(strmatch(buff,"STARTCHAR")) {
  215.         readchar();
  216.         buff = readline();
  217.         if(!strmatch(buff,"ENDCHAR")) badbdf("missing \"ENDCHAR\" line");
  218.         continue;
  219.         }
  220.         if(strmatch(buff,"ENDFONT")) break;
  221.     }
  222.     if(bmp != NULL) free(bmp);
  223. }
  224.  
  225. static void fillblank(void)
  226. {
  227.     chr *cp,*defc,*new;
  228.  
  229.     defc = getchr(defchar);
  230.     if(defc == NULL) defc = getchr(' ');
  231.     if(defc == NULL) defc = getchr(0);
  232.     if(defc == NULL) defc = fnt.chars;
  233.     fnt.minchar = fnt.chars->code;
  234.     for(cp = fnt.chars; cp != NULL; cp = cp->next) {
  235.         if((cp->next != NULL) && ((cp->code + 1) != cp->next->code)) {
  236.         new = safemalloc(sizeof(chr));
  237.         *new = *defc;
  238.         new->bmp = makebytemap(defc->width,fnt.height);
  239.         copybytemap(new->bmp,0,0,defc->bmp,0,0,defc->width,fnt.height);
  240.         new->code = cp->code + 1;
  241.         new->next = cp->next;
  242.         cp->next = new;
  243.         }
  244.         fnt.maxchar = cp->code;
  245.     }
  246. }
  247.  
  248. static void fixwidth(void)
  249. {
  250.     chr  *cp;
  251.     char **newbmp;
  252.     int  pad;
  253.  
  254.     computewidth();
  255.     if(fnt.maxwidth == fnt.minwidth) return;
  256.     for(cp = fnt.chars; cp != NULL; cp = cp->next) {
  257.         if(cp->width == fnt.maxwidth) continue;
  258.         pad = fnt.maxwidth - cp->width;
  259.         if((pad & 1) != 0) {
  260.         int maxcol = -1;
  261.         int mincol = cp->width + 1;
  262.         int ii;
  263.         for(ii = 0; ii < cp->width; ii++) {
  264.             if(colbit(cp->bmp,ii)) {
  265.             if(ii > maxcol) maxcol = ii;
  266.             if(ii < mincol) mincol = ii;
  267.             }
  268.         }
  269.         if(maxcol >= mincol) {
  270.             if(mincol > (cp->width - maxcol - 1))
  271.             pad >>= 1;
  272.             else pad = (pad >> 1) + 1;
  273.         }
  274.         }
  275.         else pad >>= 1;
  276.         newbmp = makebytemap(fnt.maxwidth,fnt.height);
  277.         copybytemap(newbmp,pad,0,cp->bmp,0,0,cp->width,fnt.height);
  278.         free(cp->bmp);
  279.         cp->bmp = newbmp;
  280.         cp->width = fnt.maxwidth;
  281.     }
  282. }
  283.  
  284. void readbdf()
  285. {
  286.     ascent  = 0;
  287.     descent = 0;
  288.     defchar = 0;
  289.     readfont();
  290.     fillblank();
  291.     if(fnt.isfixed) fixwidth();
  292.     fnt.baseline = fontbb.bbh + fontbb.bby;
  293.     fnt.undwidth = (fnt.height / 20) + 1;
  294. }
  295.  
  296.